package com.tank.designstudy.abstractfactory;

import java.io.IOException;

//不光工厂是抽象的，产品也是抽象的
/**
 * @author sunhongmin
 *         不但工厂是抽象的，产品是抽象的，而且有多个产品需要创建，因此，这个抽象工厂会对应到多个实际工厂，每个实际工厂负责创建多个实际产品
 *
 */
public class AbstractFactoryStudy {
	public static void main(String[] args) throws IOException {
		// 实例化第一家公司
		AbstractFactory factory = new FastFactory();
		HtmlDocument html = factory.createHtml("note.md");
		html.toHtml();
		html.save("htmlpath");
		WordDocument word = factory.createWord("note.md");
		word.save("wordpath");

		////// 当写完了第二家公司的实现后，就可以灵活的切换不同的实现了 注意 只需要给一个new就可以了
		// 当进一步把new 的逻辑用工厂方法实现，那么就真正实现了灵活切换
		AbstractFactory factory2 = new GoogleFactory();
		HtmlDocument html2 = factory.createHtml("note.md");
		html.toHtml();
		html.save("htmlpath");
		WordDocument word2 = factory.createWord("note.md");
		word.save("wordpath");
	}

}

/**
 * @author sunhongmin 抽象工厂类，提供另两个产品工厂的生产
 */
interface AbstractFactory {
	HtmlDocument createHtml(String md);

	WordDocument createWord(String md);
}

// html 抽象产品工厂，提供html转换和保存
interface HtmlDocument {
	String toHtml();

	void save(String path) throws IOException;
}

// word 抽象产品工厂，提供word转换和保存
interface WordDocument {
	void save(String path) throws IOException;
}

// 第一家提供商，需要实现html抽象工厂和word抽象工厂01
class FastHtmlDocument implements HtmlDocument {
	private String md;

	public FastHtmlDocument(String md) {
		this.md = md;
	}

	@Override
	public String toHtml() {
		System.out.println("TO HTML ...");
		return "FORMAT SUCCESS";
	}

	@Override
	public void save(String path) throws IOException {
		System.out.println("SAVE HTML TO PATH ... " + path);
	}
}

// 第一家提供商，需要实现html抽象工厂和word抽象工厂02
class FastWordDocument implements WordDocument {
	private String md;

	public FastWordDocument(String md) {
		this.md = md;
	}

	@Override
	public void save(String path) throws IOException {
		System.out.println("SAVE WORD TO PATH ... " + path);
	}
}

// 第一家提供商的产品工厂，用来生产产品提供转换服务
class FastFactory implements AbstractFactory {
	@Override
	public HtmlDocument createHtml(String md) {
		return new FastHtmlDocument(md);
	}

	@Override
	public WordDocument createWord(String md) {
		return new FastWordDocument(md);
	}
}

// =====分割线，代码写到这，至少可以实现整个产品逻辑了，下面的代码更近一步，展示设计模式的一大原则，对修改关闭，对拓展开放
// 第二家提供商，同样需要实现html抽象工厂和word抽象工厂01
class GooleHtmlDocument implements HtmlDocument {
	private String md;

	public GooleHtmlDocument(String md) {
		this.md = md;
	}

	@Override
	public String toHtml() {
		System.out.println("GooleHtmlDocument TO HTML ...");
		return "GooleHtmlDocument FORMAT SUCCESS";
	}

	@Override
	public void save(String path) throws IOException {
		System.out.println("GooleHtmlDocument SAVE HTML TO PATH ... " + path);
	}
}

// 第二家提供商，同样实现html抽象工厂和word抽象工厂02
class GooleWordDocument implements WordDocument {
	private String md;

	public GooleWordDocument(String md) {
		this.md = md;
	}

	@Override
	public void save(String path) throws IOException {
		System.out.println("GooleWordDocument SAVE WORD TO PATH ... " + path);
	}
}

// 第二家提供商的产品工厂，用来生产产品提供转换服务
class GoogleFactory implements AbstractFactory {
	@Override
	public HtmlDocument createHtml(String md) {
		return new GooleHtmlDocument(md);
	}

	@Override
	public WordDocument createWord(String md) {
		return new GooleWordDocument(md);
	}
}
